const RegExps = {
  phone: /^((0\d{2,3}-\d{7,8})|(?:(?:\+|00)86)?1[3-9]\d{9})$/,
  email:
    /^[A-Za-zd0-9]+([-_.][A-Za-zd]+)*@([A-Za-zd0-9]+[-.])+[A-Za-zd0-9]{2,5}$/,
  /** 不少于6位字符，且不能有中文；建议包含字母、数字和符号 */
  password: /^[A-Za-zd0-9.-_*!@`+#$&]{6,16}$/,
};
const Utils = {
  /** 是否移动端 */
  isMobile: () => {
    const pattern =
      /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|OperaMini/i;
    return pattern.test(navigator.userAgent); //  ? "Mobile" : "Desktop";
  },
  /*
    防抖函数, 电梯关闭
    使用: 1
    document.getElementById('app').onclick = tools.debounce(2000, callback)
    使用: 2
    let bind_debounce = tools.debounce(2000, callback)
    document.getElementById('app').onclick = ()=>{ bind_debounce(); }
  */
  debounce: (delay: number, callback: Function) => {
    let timer: number | null = null;
    return function (this: any, ...args: any[]) {
      if (timer) clearTimeout(timer);
      timer = setTimeout(
        () => {
          callback.apply(this, args);
        },
        delay,
        ...args
      );
    };
  },
  /*
      截流函数, 技能CD
      使用: 
      let bind_throttle = tools.throttle(2000, callback)
      document.getElementById('app').onclick = ()=>{ bind_throttle(); }
  */
  throttle: (delay: number, callback: Function) => {
    let timer: number | null = null;
    return function (this: any, ...args: any[]) {
      if (!timer)
        timer = setTimeout(
          () => {
            callback.apply(this, args);
            timer = null;
          },
          delay,
          ...args
        );
    };
  },
  /**
   * 用value来覆盖target, 只覆盖公有的数据
   */
  coverObject: (target: any, value: any) => {
    for (const key in value) {
      if (Object.prototype.hasOwnProperty.call(target, key)) {
        if (Object.prototype.toString.call(target[key]) === "[object Object]") {
          Utils.coverObject(target[key], value[key]);
        } else {
          target[key] = value[key];
        }
      }
    }
  },
  /**
   * 格式化日期
   * @example Utils.formatDate(1603264465956, 'Y-M-D h:m:s')
   */
  formatDate: (
    value: string | number | Date,
    format: string = "Y-M-D h:m:s"
  ) => {
    // ios 和 mac 系统中，带横杆的字符串日期是格式不了的，这里做一下判断处理
    if (
      typeof value === "string" &&
      new Date(value).toString() === "Invalid Date"
    ) {
      value = value.replace(/-/g, "/");
    }
    function formatNumber(n: number) {
      return `0${n}`.slice(-2);
    }
    const date = new Date(value);
    const formatList = ["Y", "M", "D", "h", "m", "s"];
    const resultList = [];
    resultList.push(date.getFullYear().toString());
    resultList.push(formatNumber(date.getMonth() + 1));
    resultList.push(formatNumber(date.getDate()));
    resultList.push(formatNumber(date.getHours()));
    resultList.push(formatNumber(date.getMinutes()));
    resultList.push(formatNumber(date.getSeconds()));
    for (let i = 0; i < resultList.length; i++) {
      format = format.replace(formatList[i], resultList[i]);
    }
    return format;
  },
  /**
   * 请求query参数转string
   * @example  Utils.params2string({kd:'ts', time: '124584574'}) => kd=ts&time=124584574
   */
  params2string: (params: any) => {
    let result = "";
    for (const key in params) {
      result += `&${key}=${params[key]}`;
    }
    return result.slice(1);
  },
  /**
   * 复制文本到剪切板, 使用到dom操作
   */
  str2clipboard: (
    text: string,
    successCallback?: Function,
    failCallback?: Function
  ) => {
    text = text.replace(/(^\s*)|(\s*$)/g, "");
    const id = "the-clipboard";
    let clipboard: HTMLTextAreaElement = document.getElementById(
      id
    ) as HTMLTextAreaElement;
    if (!clipboard) {
      clipboard = document.createElement("textarea");
      clipboard.id = id;
      clipboard.readOnly = true;
      clipboard.style.cssText =
        "font-size: 15px; position: fixed; top: -1000%; left: -1000%;";
      document.body.appendChild(clipboard);
    }
    clipboard.value = text;
    clipboard.select();
    clipboard.setSelectionRange(0, text.length);
    const state = document.execCommand("copy");
    if (state) {
      successCallback && successCallback();
    } else {
      failCallback && failCallback("复制失败");
    }
  },
  openLink: (
    link: string,
    target: "_blank" | "_self" | "_parent" | "_top" = "_blank"
  ) => {
    const label = document.createElement("a");
    label.href = link;
    label.target = target;
    document.body.appendChild(label);
    label.click();
    document.body.removeChild(label);
  },
  /** 引入图片资源, 可作为src的属性 */
  url: (path: string) => {
    let path_relative;
    if (path.startsWith("@/")) {
      path_relative = "../" + path.slice(2);
    } else {
      path_relative = "../assets/default/pathMustStartWith@.png";
      console.error(
        "Utils.url函数参数不正确: 使用url引入资源必须以'@/'路径开头"
      );
    }
    return new URL(path_relative, import.meta.url).href;
  },
    /**
   * 修改属性值-逐个属性深层修改|只修改之前存在的值
   * @param target 修改的目标
   * @param value 修改的内容
   */
  modifyData: <T>(target: T, value: T) => {
    for (const key in value) {
      if (Object.prototype.hasOwnProperty.call(target, key)) {
        if (Object.prototype.toString.call(target[key]) === "[object Object]") {
          Utils.modifyData(target[key], value[key]);
        } else {
          target[key] = value[key];
        }
      }
    }
  },
  /** 数字千分位显示 */
  formatNumber2PriceView (number: number|string) {
    const num = String(number);
    const reg = /\d{1,3}(?=(\d{3})+$)/g;
    const res = num.replace(/^(-?)(\d+)((\.\d+)?)$/, function(match, s1, s2, s3){
      return s1 + s2.replace(reg, '$&,') + s3
    })
    return res;
  }
};

export { Utils };
